home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 16 / AMIGAplus Sonderheft 16 (1998)(ICP)(DE)[!].iso / pd / anwendungen / xpk_source / xpkmaster / open.c < prev    next >
C/C++ Source or Header  |  1998-08-27  |  16KB  |  512 lines

  1. #ifndef XPKMASTER_OPEN_C
  2. #define XPKMASTER_OPEN_C
  3.  
  4. /* Routinesheader
  5.  
  6.     Name:        open.c
  7.     Main:        xpkmaster
  8.     Versionstring:    $VER: open.c 1.17 (26.08.1998)
  9.     Author:        SDI
  10.     Distribution:    Freeware
  11.     Description:    Opening and initialisation routines for XPK files
  12.  
  13.  1.0   06.10.96 : first real version
  14.  1.1   28.10.96 : reincluded A4 support
  15.  1.2   03.03.97 : added Prefs, corrected length recognition
  16.  1.3   07.03.97 : fixed prefs handling, new features
  17.  1.4   09.03.97 : added DEBUG statement
  18.  1.5   28.03.97 : auto decrunch password
  19.  1.6   29.03.97 : fixed prefs stuff, moved getinlen into hooks
  20.  1.7   31.03.97 : changed the password stuff
  21.  1.8   19.12.97 : added xfdmaster.library support
  22.  1.9   22.12.97 : fixed auto password problem
  23.  1.10  27.12.97 : fixed GetPassword error
  24.  1.11  09.01.98 : better key handling
  25.  1.12  21.01.98 : added password verification for packing
  26.  1.13  24.01.98 : fixed xfdmaster support a bit
  27.  1.14  17.02.98 : fixe long file problem added in last version
  28.  1.15  21.02.98 : uses new style register definition
  29.  1.16  26.03.98 : some optimizations
  30.  1.17  26.08.98 : may skip reading insize for packing, when no inhook
  31. */
  32.  
  33. #include <xpk/xpkprefs.h>
  34. #include <exec/memory.h>
  35. #include <proto/exec.h>
  36. #include <proto/dos.h>
  37. #include <proto/xpkmaster.h>
  38. #include <proto/xpksub.h>
  39. #include <proto/xfdmaster.h>
  40. #include "xpkmaster.h"
  41. #include "texts.h"
  42.  
  43. static const struct XpkInfo DONTInfo = { 1,0,0,1,"DONT","Copy",
  44. 0, 0x55534552, XPKIF_PK_CHUNK|XPKIF_UP_CHUNK, DEFAULTCHUNKSIZE, 1,
  45. DEFAULTCHUNKSIZE,0,0,0,0,100,0,0,0,0,0,0,0,0};
  46. /* XpkMode is not initialized! Should not be used anywhere */
  47.  
  48. static LONG xpkopenwrite(struct XpkBuffer **, struct TagItem *);
  49. static LONG GetPrefsPacker(struct XpkBuffer *);
  50. static LONG GetPassword(struct XpkBuffer *, struct TagItem *, ULONG);
  51. static struct XpkTypeData *BufRecog(ULONG, struct XpkBuffer *,
  52.   struct XpkPrefsSemaphore *);
  53.  
  54. XPK_ALLINONE ASM(LONG) xpkopen(REG(a0, struct XpkBuffer **xbufp),
  55. REG(a1, struct TagItem *tags), REG(d2, ULONG examine A4PROTO))
  56. {
  57.   struct XpkBuffer     *xbuf;
  58.   struct XpkStreamHeader *globhdr;
  59.   struct XpkFib         *fib;
  60.  
  61. #if defined(DEBUG) && defined(SUPPORT_A4)
  62.   DebugRunTime("xpkopen: A4 = %ld", a4);
  63. #elif defined (DEBUG)
  64.   DebugRunTime("xpkopen");
  65. #endif
  66.  
  67.   if(!(*xbufp = xbuf = initxbuf()))
  68.     return parseerrortags(tags, XPKERR_NOMEM);
  69.  
  70. #ifdef SUPPORT_A4
  71.   xbuf->xb_regA4 = a4;
  72. #endif
  73.  
  74.   globhdr = &xbuf->xb_Headers.h_Glob;
  75.   fib = &xbuf->xb_Fib;
  76.  
  77.   if(parsebuftags(xbuf, tags))
  78.     goto Abort;
  79.  
  80.   if(xbuf->xb_Flags & XMF_PACKING) /* Call pack open function */
  81.     return xpkopenwrite(xbufp, tags);
  82.  
  83.   if(!hookread(xbuf, XIO_READ, globhdr, 4)) /* Read first longword */
  84.   {
  85.     if(xbuf->xb_Result != XPKERR_TRUNCATED)
  86.       goto Abort;
  87.     /* else handle now as uncompressed file */
  88.   }
  89.  
  90.   /***************************** Standard XPK file **********************/
  91.   if(globhdr->xsh_Pack == XPK_COOKIE)
  92.   {
  93.     UWORD exthlen = 0;        /* size of extended header if present */
  94.     struct Library * XpkSubBase;
  95.  
  96.     xbuf->xb_Format = XPKMODE_UPSTD;
  97.  
  98.     /* Read rest of the global header */
  99.     if(!hookread(xbuf, XIO_READ, (STRPTR) globhdr + 4, sizeof(struct XpkStreamHeader) - 4))
  100.       goto Abort;
  101.  
  102.     if(hchecksum((STRPTR) globhdr, sizeof(struct XpkStreamHeader)))
  103.     {
  104.       xbuf->xb_Result = XPKERR_CHECKSUM;
  105.       goto Abort;
  106.     }
  107.  
  108.     if(globhdr->xsh_Flags & XPKSTREAMF_LONGHEADERS)
  109.       xbuf->xb_Headers.h_LocSize = sizeof(struct XpkChunkHdrLong);
  110.     else
  111.       xbuf->xb_Headers.h_LocSize = sizeof(struct XpkChunkHdrWord);
  112.  
  113.     if(globhdr->xsh_Flags & XPKSTREAMF_EXTHEADER)
  114.     {
  115.       if(!hookread(xbuf, XIO_READ, &exthlen, sizeof(UWORD)))
  116.     goto Abort;
  117.       if(!hookread(xbuf, XIO_READ, NULL, exthlen))
  118.     goto Abort;
  119.       exthlen += sizeof(UWORD);    /* for unwinding while XpkExamine */
  120.     }
  121.  
  122.     if(!hookread(xbuf, XIO_READ, &xbuf->xb_Headers.h_Loc,
  123.     xbuf->xb_Headers.h_LocSize))    /* first lochdr */
  124.       goto Abort;
  125.  
  126.     fib->xf_CCur = sizeof(struct XpkStreamHeader);
  127.     updatefib(xbuf);
  128.     xbuf->xb_InLen = fib->xf_CLen;
  129.  
  130.     if(!(XpkSubBase = opensub(xbuf, globhdr->xsh_Type)))
  131.       goto Abort;
  132.  
  133.     if(globhdr->xsh_SubVrs > xbuf->xb_SubInfo->xi_LibVersion)
  134.     {
  135.       xbuf->xb_Result = XPKERR_OLDSUBLIB;
  136.       goto Abort;
  137.     }
  138.  
  139.     xbuf->xb_Prog.xp_Activity = xbuf->xb_SubInfo->xi_UnpackMsg ?
  140.       xbuf->xb_SubInfo->xi_UnpackMsg : strings[TXT_UNPACKING_UPPER];
  141.     xbuf->xb_Prog.xp_PackerName = xbuf->xb_SubInfo->xi_Name;
  142.     xbuf->xb_LastMsg = xbuf->xb_SubInfo->xi_UnpackedMsg ?
  143.       xbuf->xb_SubInfo->xi_UnpackedMsg : strings[TXT_UNPACKED];
  144.  
  145.     if(globhdr->xsh_Flags & XPKSTREAMF_PASSWORD)
  146.       fib->xf_Flags |= XPKFLAGS_PASSWORD;
  147.  
  148.     if(examine && !hookread(xbuf, XIO_SEEK, 0,
  149.     -(sizeof(struct XpkStreamHeader) + xbuf->xb_Headers.h_LocSize+exthlen)))
  150.       goto Abort;
  151.  
  152.     goto Exit;
  153.   }
  154.  
  155.   if(!hookread(xbuf, XIO_SEEK, 0, -xbuf->xb_RMsg.xmm_Size))
  156.     goto Abort; /* redo last read bytes */
  157.  
  158.   if(xbuf->xb_InLen == 0xFFFFFFFF)
  159.   {
  160.     if(!hookread(xbuf, XIO_TOTSIZE, 0, 0))    /* get input length */
  161.       goto Abort;
  162.     else if(xbuf->xb_RMsg.xmm_Size)
  163.       xbuf->xb_InLen = xbuf->xb_RMsg.xmm_Size;
  164.   }
  165.  
  166.   fib->xf_CLen = xbuf->xb_InLen;
  167.  
  168. #ifdef USE_POWERPACKER
  169.   /***************************** PowerPacker file ***********************/
  170.   if(globhdr->xsh_Pack == PP_COOKIE)
  171.   {
  172.     ULONG outsize;
  173.  
  174.     xbuf->xb_Format = XPKMODE_UPPP;
  175.  
  176.     if(!hookread(xbuf, XIO_SEEK, 0, xbuf->xb_InLen - 4))
  177.       goto Abort;                /* 4 Bytes before EOF */
  178.     if(!hookread(xbuf, XIO_READ, &outsize, 4))
  179.       goto Abort;
  180.     if(!hookread(xbuf, XIO_SEEK, 0, - (xbuf->xb_InLen - 4) - (examine<<2)))
  181.       goto Abort;    /* back to start when examine, else 4 bytes later */
  182.  
  183.     outsize >>= 8;
  184.  
  185. #ifdef DEBUG
  186.     DebugRunTime("xpkopen: PP, InLen %ld, OutLen %ld", xbuf->xb_InLen,
  187.     outsize);
  188. #endif
  189.  
  190.     fib->xf_Type = XPKTYPE_PACKED;
  191.     fib->xf_ULen = outsize;
  192.     fib->xf_NLen = outsize + XPK_MARGIN;
  193.     fib->xf_ID = PP_COOKIE;
  194.     percentages(fib);
  195.     xbuf->xb_Prog.xp_Activity = strings[TXT_UNPACKING_UPPER];
  196.     xbuf->xb_Prog.xp_PackerName = "PowerPacker";
  197.     xbuf->xb_LastMsg = strings[TXT_UNPACKED];
  198.  
  199.     if(!examine && !(xbuf->xb_SubBase = OpenLibrary("powerpacker.library", 0)))
  200.     {
  201.       xbuf->xb_Result = XPKERR_MISSINGLIB;
  202.       goto Abort;
  203.     }
  204.  
  205.     goto Exit;
  206.   }
  207. #endif /* USE_POWERPACKER */
  208.  
  209.   /**************************** xfdmaster file **************************/
  210.   if(xbuf->xb_Flags & XMF_XFD &&
  211.   (xbuf->xb_SubBase = OpenLibrary("xfdmaster.library", 38)))
  212.   {
  213.     struct xfdMasterBase *xfdMasterBase = (struct xfdMasterBase *) xbuf->xb_SubBase;
  214.     struct xfdBufferInfo *xbi;
  215.  
  216.     if(!(xbi = xbuf->xb_xfd = (struct xfdBufferInfo *) xfdAllocObject(XFDOBJ_BUFFERINFO)))
  217.       goto Abort;
  218.     if(!(xbi->xfdbi_SourceBuffer = hookread(xbuf, XIO_READ, 0, xbuf->xb_InLen)))
  219.       goto Abort;
  220.     xbi->xfdbi_SourceBufLen = xbuf->xb_InLen;
  221.     xbi->xfdbi_Flags = XFDFF_RECOGEXTERN|XFDFF_RECOGTARGETLEN|XFDFF_RECOGUSERTARGET;
  222.  
  223.     if(xfdRecogBuffer(xbi) && (xbi->xfdbi_PackerFlags & XFDPFF_DATA) &&
  224.     (LONG) xbi->xfdbi_FinalTargetLen != -1)
  225.     {
  226.       xbuf->xb_Format = XPKMODE_UPXFD;
  227.       if(xbi->xfdbi_PackerFlags & XFDPFF_PASSWORD)
  228.         xbuf->xb_Fib.xf_Flags |= XPKFLAGS_PASSWORD;
  229.       if(xbi->xfdbi_PackerFlags & XFDPFF_KEY16)
  230.         xbuf->xb_Fib.xf_Flags |= XPKFLAGS_KEY16;
  231.       if(xbi->xfdbi_PackerFlags & XFDPFF_KEY32)
  232.         xbuf->xb_Fib.xf_Flags |= XPKFLAGS_KEY32;
  233.       fib->xf_Type = XPKTYPE_PACKED;
  234.       fib->xf_ULen = xbi->xfdbi_FinalTargetLen;
  235.       fib->xf_NLen = xbi->xfdbi_MinTargetLen;
  236.       fib->xf_ID = XFD_COOKIE;
  237.       percentages(fib);
  238.       xbuf->xb_Prog.xp_Activity = strings[TXT_UNPACKING_UPPER];
  239.       xbuf->xb_Prog.xp_PackerName = "XFDMaster";
  240.       xbuf->xb_LastMsg = strings[TXT_UNPACKED];
  241.  
  242.       if(examine && !hookread(xbuf, XIO_SEEK, 0, -xbuf->xb_InLen))
  243.         goto Abort; /* return to start */
  244.  
  245. #ifdef DEBUG
  246.       DebugRunTime("xpkopen: XFD, InLen %ld, OutLen %ld, NLen %ld",
  247.       xbuf->xb_InLen, fib->xf_ULen, fib->xf_NLen);
  248. #endif
  249.       goto Exit;
  250.     } /* xfdRecogBuffer */
  251.  
  252.     if(!hookread(xbuf, XIO_SEEK, 0, -xbuf->xb_InLen))
  253.       goto Abort; /* return to start */
  254.   }
  255.  
  256.   /*************************** Uncompressed file ************************/
  257.   if(examine || xbuf->xb_Flags & XMF_PASSTHRU)        /* Unpacked */
  258.   {
  259.     xbuf->xb_Format = XPKMODE_UPUP;
  260.  
  261.     fib->xf_Type = XPKTYPE_UNPACKED;
  262.     fib->xf_ULen = xbuf->xb_InLen;
  263.     fib->xf_NLen = Min(DEFAULTCHUNKSIZE, xbuf->xb_InLen) + XPK_MARGIN;
  264.     fib->xf_ID = ROW_OF_MINUS;
  265.  
  266.     xbuf->xb_Prog.xp_Activity = strings[TXT_READING];
  267.     xbuf->xb_Prog.xp_PackerName = "Master";
  268.     xbuf->xb_LastMsg = strings[TXT_READ];
  269.  
  270.     xbuf->xb_Result = XPKERR_OK;  /* if != 0 it was XPKERR_TRUNCATED */
  271.  
  272.     goto Exit;
  273.   }
  274.  
  275.   xbuf->xb_Result = XPKERR_NOTPACKED;    /* Can't unpack, can't passthru */
  276.  
  277. Abort:
  278.   *xbufp = 0;
  279.   return XpkClose((struct XpkFib *) xbuf);
  280.  
  281. Exit:
  282.   if(!examine && (
  283.   ((fib->xf_Flags & XPKFLAGS_PASSWORD) && !xbuf->xb_Password) ||
  284.   ((fib->xf_Flags & XPKFLAGS_KEY16) && !(xbuf->xb_Flags & XMF_KEY16)) ||
  285.   ((fib->xf_Flags & XPKFLAGS_KEY32) && !(xbuf->xb_Flags & XMF_KEY32)))
  286.   && (xbuf->xb_Result = GetPassword(xbuf, tags, FALSE)))
  287.       goto Abort;
  288.   return XPKERR_OK;
  289. }
  290.  
  291. /***************************** Open for packing *************************/
  292. static LONG xpkopenwrite(struct XpkBuffer **xbufp, struct TagItem *tags)
  293. {
  294.   struct XpkBuffer        *xbuf        = *xbufp;
  295.   struct XpkStreamHeader    *globhdr    = &xbuf->xb_Headers.h_Glob;
  296.   struct Library        *XpkSubBase;
  297.   LONG                 res;
  298.  
  299.   xbuf->xb_Format = XPKMODE_PKSTD;
  300.  
  301.   if(xbuf->xb_InLen == 0xFFFFFFFF && xbuf->xb_RHook)
  302.   {
  303.     if(!hookread(xbuf, XIO_TOTSIZE, 0, 0))    /* get input length */
  304.       return xbuf->xb_Result;
  305.     else if(xbuf->xb_RMsg.xmm_Size)
  306.       xbuf->xb_InLen = xbuf->xb_RMsg.xmm_Size;
  307.   }
  308.  
  309.   if(!(XpkSubBase = xbuf->xb_SubBase) &&  /* Do we know the sublib? */
  310.   (xbuf->xb_Result = GetPrefsPacker(xbuf)))
  311.     goto Abort; /* no sublib and no prefs packer finder */
  312.  
  313.   if(xbuf->xb_Password && !(xbuf->xb_SubInfo->xi_Flags & XPKIF_ENCRYPTION))
  314.   {
  315.     xbuf->xb_Result = XPKERR_NOCRYPT;
  316.     goto Abort;
  317.   }
  318.  
  319.   if(!xbuf->xb_Password && (xbuf->xb_SubInfo->xi_Flags & XPKIF_NEEDPASSWD))
  320.   { /* automatic password requester */
  321.     if((xbuf->xb_Result = GetPassword(xbuf, tags, TRUE)))
  322.       goto Abort;
  323.   }
  324.  
  325.   if(!(xbuf->xb_Flags & XMF_LOSSYOK) &&
  326.   xbuf->xb_SubInfo->xi_Flags & XPKIF_LOSSY)
  327.   {
  328.     xbuf->xb_Result = XPKERR_LOSSY;
  329.     goto Abort;
  330.   }
  331.  
  332.   if(xbuf->xb_PackingMode > 100)    /* Is packing mode valid? */
  333.     xbuf->xb_PackingMode = 100;        /* Use max */
  334.  
  335.   if(xbuf->xb_InLen != 0xFFFFFFFF)
  336.   {
  337.     if(!hookwrite(xbuf, XIO_TOTSIZE, 0, ROUNDLONG
  338.     (xbuf->xb_InLen + (xbuf->xb_InLen >> 5)) + (XPK_MARGIN<<1)))
  339.       goto Abort;
  340.   }
  341.  
  342.   /************************* Find the chunk size ************************/
  343.   if((xbuf->xb_ChunkSize == 0) &&
  344.   ((xbuf->xb_ChunkSize = xbuf->xb_SubInfo->xi_DefPkInChunk) == 0))
  345.     xbuf->xb_ChunkSize = DEFAULTCHUNKSIZE;
  346.   if(xbuf->xb_ChunkSize < xbuf->xb_SubInfo->xi_MinPkInChunk)
  347.     xbuf->xb_ChunkSize = xbuf->xb_SubInfo->xi_MinPkInChunk;
  348.   if((xbuf->xb_SubInfo->xi_MaxPkInChunk) &&
  349.   (xbuf->xb_ChunkSize > xbuf->xb_SubInfo->xi_MaxPkInChunk))
  350.     xbuf->xb_ChunkSize = xbuf->xb_SubInfo->xi_MaxPkInChunk;
  351.  
  352.   /************************ Prepare global header ***********************/
  353.   globhdr->xsh_Pack = 0;        /* Initialize the global header */
  354.   globhdr->xsh_Type = xbuf->xb_SubID;
  355.  
  356.   if(xbuf->xb_ChunkSize > 65000) /* (0xFFFF-XPK_MARGIN) and some bytes security */
  357.     globhdr->xsh_Flags |= XPKSTREAMF_LONGHEADERS;
  358.   if(xbuf->xb_Password)
  359.     globhdr->xsh_Flags |= XPKSTREAMF_PASSWORD;
  360.  
  361.   xbuf->xb_Headers.h_LocSize = globhdr->xsh_Flags & XPKSTREAMF_LONGHEADERS
  362.     ? sizeof (struct XpkChunkHdrLong)
  363.     : sizeof (struct XpkChunkHdrWord);
  364.  
  365.   memset(globhdr->xsh_Initial, 0xff, 16);    /* Read first 16 bytes */
  366.  
  367.   xbuf->xb_Prog.xp_Activity = xbuf->xb_SubInfo->xi_PackMsg ?
  368.   xbuf->xb_SubInfo->xi_PackMsg : strings[TXT_PACKING_UPPER];
  369.   xbuf->xb_Prog.xp_PackerName = xbuf->xb_SubInfo->xi_Name;
  370.   xbuf->xb_LastMsg = xbuf->xb_SubInfo->xi_PackedMsg ?
  371.   xbuf->xb_SubInfo->xi_PackedMsg : strings[TXT_PACKED];
  372.  
  373. Abort:
  374.   xbuf->xb_Fib.xf_NLen = Min(xbuf->xb_InLen - xbuf->xb_Fib.xf_UCur,
  375.   xbuf->xb_ChunkSize);
  376.  
  377.   if((res = xbuf->xb_Result))
  378.     res = XpkClose((struct XpkFib *) xbuf);
  379.  
  380.   return res;
  381. }
  382.  
  383. typedef ASM(struct XpkTypeData *) (*RecogFunc) (REG(a0, STRPTR),
  384.     REG(a1, STRPTR), REG(d0, ULONG), REG(d1, ULONG),
  385.     REG(a2, struct TagItem *));
  386.  
  387. static LONG GetPrefsPacker(struct XpkBuffer *xbuf)
  388. {
  389.   LONG ret = XPKERR_UNKNOWN;
  390.   struct XpkPrefsSemaphore *sem;
  391.   ULONG bufsize;
  392.   struct XpkTypeData *td = 0;
  393.  
  394.   if((xbuf->xb_Flags & XMF_NOPREFS) || !xbuf->xb_RHook)
  395.     return XPKERR_BADPARAMS;
  396.   if(!(sem = GetPrefsSem()))
  397.     return XPKERR_NOFUNC;
  398.  
  399.   bufsize = Min(xbuf->xb_InLen, sem->xps_RecogSize);
  400.  
  401.   if(sem->xps_RecogFunc && (td = BufRecog(bufsize, xbuf, sem)) ==
  402.   (struct XpkTypeData *) 0xFFFFFFFF)
  403.     td = BufRecog(xbuf->xb_InLen, xbuf, sem);
  404.  
  405.   if(!td || td == (struct XpkTypeData *) 0xFFFFFFFF)
  406.     td = sem->xps_MainPrefs ? sem->xps_MainPrefs->xmp_DefaultType : 0;
  407.  
  408.   if(td)
  409.   {
  410.     if(td->xtd_Flags & XTD_NoPack)
  411.     {
  412.       xbuf->xb_Flags |= XMF_NOPACK;
  413.       xbuf->xb_SubInfo = (struct XpkInfo *) &DONTInfo;
  414.       ret = XPKERR_OK;
  415.     }
  416.     else if(!(td->xtd_Flags & XTD_ReturnError))
  417.     {
  418.       struct Library *XpkSubBase;
  419.       struct XpkInfo *subinfo;
  420.  
  421.       if((XpkSubBase = opensub(xbuf, td->xtd_StdID)))
  422.       {
  423.     ret = XPKERR_OK;
  424.         subinfo = XpksPackerInfo();
  425.  
  426.         xbuf->xb_ChunkSize = td->xtd_ChunkSize;
  427.         xbuf->xb_PackingMode = ( td->xtd_Mode ? td->xtd_Mode :
  428.           subinfo->xi_DefMode);
  429. //    if(!(xbuf->xb_Password) && td->xtd_Password && 
  430. //    (xbuf->xb_PasswordSize = strlen(td->xtd_Password)))
  431. //    {
  432. //      /* we need a buffer including end byte! --> ++size */
  433. //      if(!(xbuf->xb_Password = (STRPTR)
  434. //      AllocMem(++xbuf->xb_PasswordSize, MEMF_PUBLIC)))
  435. //        ret = XPKERR_NOMEM;
  436. //        else
  437. //      {
  438. //        xbuf->Flags |= XMF_OWNPASSWORD;
  439. //        CopyMem(td->xtd_Password, xbuf->xb_Password, xbuf->xb_PasswordSize);
  440. //      }
  441. //    }
  442.       }
  443.     }
  444.     else
  445.       ret = XPKERR_NOMETHOD;
  446.   }
  447.  
  448.   if(td->xtd_Memory && td->xtd_MemorySize)
  449.     FreeMem(td->xtd_Memory, td->xtd_MemorySize);
  450.  
  451.   ReleaseSemaphore((struct SignalSemaphore *) sem);
  452.   return ret;
  453. }
  454.  
  455. static LONG GetPassword(struct XpkBuffer *xbuf, struct TagItem *tags,
  456. ULONG verify)
  457. {
  458.  if(xbuf->xb_Flags & XMF_AUTOPASSWD)
  459.  {
  460.    if(xbuf->xb_Fib.xf_Flags & XPKFLAGS_KEY32)
  461.    {
  462.      xbuf->xb_Result = XpkPassRequestTags(XPK_Key32BitPtr,
  463.      &xbuf->xb_PassKey32, TAG_MORE, tags, TAG_DONE);
  464.      xbuf->xb_Flags |= XMF_KEY32;
  465.    }
  466.    else if(xbuf->xb_Fib.xf_Flags & XPKFLAGS_KEY16)
  467.    {
  468.      xbuf->xb_Result = XpkPassRequestTags(XPK_Key16BitPtr,
  469.      &xbuf->xb_PassKey16, TAG_MORE, tags, TAG_DONE);
  470.      xbuf->xb_Flags |= XMF_KEY16;
  471.    }
  472.    else
  473.    {
  474.      if(!(xbuf->xb_Password = (STRPTR) AllocMem(AUTO_PASS_SIZE, MEMF_PUBLIC)))
  475.        return XPKERR_NOMEM;
  476.      xbuf->xb_PasswordSize = AUTO_PASS_SIZE;
  477.      xbuf->xb_Flags |= XMF_OWNPASSWORD; /* must be freed later */
  478.  
  479.      xbuf->xb_Result = XpkPassRequestTags(XPK_PasswordBuf,
  480.      xbuf->xb_Password, XPK_PassBufSize, xbuf->xb_PasswordSize,
  481.      XPK_PassVerify, verify, TAG_MORE, tags, TAG_DONE);
  482.    }
  483.  
  484.    return xbuf->xb_Result;
  485.  }
  486.  return XPKERR_NEEDPASSWD;
  487. }
  488.  
  489. static struct XpkTypeData *BufRecog(ULONG bufsize, struct XpkBuffer *xbuf,
  490. struct XpkPrefsSemaphore *sem)
  491. {
  492.   STRPTR bufptr;
  493.   struct XpkTypeData *ret = 0;
  494.   struct TagItem tag[] = {
  495.   { XPK_FileName, 0},
  496.   { XPK_PackMode, 0},
  497.   { TAG_DONE, 0}};
  498.  
  499.   tag[0].ti_Data = (ULONG) xbuf->xb_Prog.xp_FileName;
  500.   tag[1].ti_Data = xbuf->xb_PackingMode;
  501.  
  502.   if((bufptr = (STRPTR) hookread(xbuf, XIO_READ, 0, bufsize)))
  503.   {
  504.     ret = (((RecogFunc) sem->xps_RecogFunc) (bufptr,
  505.     xbuf->xb_RMsg.xmm_FileName, bufsize, xbuf->xb_InLen, tag));
  506.     hookread(xbuf, XIO_SEEK, 0, -bufsize);
  507.   }
  508.   return ret;
  509. }
  510.  
  511. #endif /* XPKMASTER_OPEN_C */
  512.